package services

import (
	"encoding/json"
	"sort"
	"restaurant-system/config"
	"restaurant-system/internal/models"
)

// 计算菜品与用户偏好的匹配分数
func calculateMatchScore(dish models.Dish, preference models.UserPreference) float64 {
	score := 0.0

	// 1. 类别匹配度 (权重: 0.3)
	if containsString(preference.FavCategories, dish.Category) {
		score += 0.3
	}

	// 2. 标签匹配度 (权重: 0.25)
	dishTags := []string{}
	json.Unmarshal([]byte(dish.Tags), &dishTags)
	tagMatchCount := 0
	for _, tag := range dishTags {
		if containsString(preference.FavTags, tag) {
			tagMatchCount++
		}
	}
	if len(dishTags) > 0 {
		score += 0.25 * float64(tagMatchCount) / float64(len(dishTags))
	}

	// 3. 辣度匹配 (权重: 0.2)
	if containsString(dishTags, "特辣") && preference.SpicyLevel >= 4 {
		score += 0.2
	} else if containsString(dishTags, "中辣") && preference.SpicyLevel >= 3 {
		score += 0.2
	} else if containsString(dishTags, "微辣") && preference.SpicyLevel >= 2 {
		score += 0.2
	} else if !containsString(dishTags, "辣") && preference.SpicyLevel <= 1 {
		score += 0.2
	}

	// 4. 饮食需求匹配 (权重: 0.15)
	dietaryMatch := true
	for _, need := range preference.DietaryNeeds {
		if (need == "清淡" && containsString(dishTags, "重口味")) ||
			(need == "素食" && !containsString(dishTags, "素食")) {
			dietaryMatch = false
			break
		}
	}
	if dietaryMatch {
		score += 0.15
	}

	// 5. 过敏原检查 (权重: 0.1)
	allergyMatch := true
	for _, allergy := range preference.Allergies {
		if containsString(dishTags, allergy) {
			allergyMatch = false
			break
		}
	}
	if allergyMatch {
		score += 0.1
	}

	// 6. 检查是否在不喜欢的菜品列表中
	if containsUint(preference.DislikedDishes, dish.ID) {
		score = 0
	}

	return score
}

// 获取推荐菜品
func GetRecommendedDishes(userID uint) ([]models.Dish, error) {
	var preference models.UserPreference
	if err := config.DB.Where("user_id = ?", userID).First(&preference).Error; err != nil {
		return getDefaultRecommendations()
	}

	var allDishes []models.Dish
	if err := config.DB.Where("status = ?", "available").Find(&allDishes).Error; err != nil {
		return nil, err
	}

	// 计算每个菜品的推荐分数
	type ScoredDish struct {
		Dish  models.Dish
		Score float64
	}
	var scoredDishes []ScoredDish

	for _, dish := range allDishes {
		score := calculateMatchScore(dish, preference)
		scoredDishes = append(scoredDishes, ScoredDish{
			Dish:  dish,
			Score: score,
		})
	}

	// 按分数排序
	sort.Slice(scoredDishes, func(i, j int) bool {
		return scoredDishes[i].Score > scoredDishes[j].Score
	})

	// 返回前5个最匹配的菜品
	var recommendedDishes []models.Dish
	for i := 0; i < min(5, len(scoredDishes)); i++ {
		recommendedDishes = append(recommendedDishes, scoredDishes[i].Dish)
	}

	return recommendedDishes, nil
}

// 获取默认推荐（当用户没有偏好设置时）
func getDefaultRecommendations() ([]models.Dish, error) {
	var dishes []models.Dish
	if err := config.DB.Where("status = ?", "available").
		Order("rating DESC").
		Limit(10).
		Find(&dishes).Error; err != nil {
		return nil, err
	}
	return dishes, nil
}

// 辅助函数
func containsString(slice []string, str string) bool {
	for _, s := range slice {
		if s == str {
			return true
		}
	}
	return false
}

func containsUint(slice []uint, num uint) bool {
	for _, n := range slice {
		if n == num {
			return true
		}
	}
	return false
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
} 